home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / littleRedCap / shapes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  37.8 KB  |  1,743 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /************************************************************
  18.  
  19. Shapes Library
  20.  
  21. All shapes are available in both wire frame and filled
  22. (that is, polygonized with normals).
  23.  
  24. Calls for wire frame shapes begin with the letter 'w'. Calls
  25. for filled shapes begin with the letter 'f'.
  26.  
  27. Available shapes are:
  28.  
  29. Wire Frame    Filled        Default Size           Origin
  30. ----------    ------        ------------           ------
  31. wletterf()    fletterf()    h = 1.0, d = 1.0       center of solid
  32. wtetra()      ftetra()      b = 1.0, h = 1.0       center of solid
  33. wcube()       fcube()       unit                   center of solid
  34. wbeam()       fbeam()       x = 1.0, y = 0.2,      center of left side
  35.                             z = 0.5
  36. wocta()       focta()       unit                   center of solid
  37. wdodeca()     fdodeca()     unit                   center of solid
  38. wicosa()      ficosa()      unit                   center of solid
  39. wcone()       fcone()       h = 1.0, r_base = 1.0  center of base
  40. wcylinder()   fcylinder()   l = 1.0, r = 1.0       center of solid
  41.               fclocylinder()l = 1.0, r = 1.0       center of solid
  42. wtorus()      ftorus()      r_cross_section = .3   center of solid
  43.                             r_torus = 1.0
  44. wsphere()     fsphere()     r = 1.0                center of solid
  45. whemisphere() fhemisphere() r = 1.0                center of solid
  46.  
  47. axes()                      unit                   origin of axes
  48. beachball(c1,c2)            r = 1.0, stripes = 12  center of solid
  49.  
  50.  
  51. Changing shape defaults:
  52. Certain shapes may have their default sizes changed by calling a
  53. setup routine. This routine only needs to be called once.
  54.  
  55. setcube(float x, float y, float z);
  56. setbeam(float x, float y, float z);
  57. settorus(float rad_cross_section, float radius_torus);
  58. setbeachball(int num_stripes);
  59.  
  60. The platonic solids are defined as follows:
  61.  
  62. name    edges per facet facets  vertices    edges
  63. ----    --------------- ------  --------    -----
  64. tetra   3               4       4           6
  65. cube    4               6       8           12
  66. octa    3               8       6           12
  67. dodeca  5               12      20          30
  68. icoso   3               20      12          30
  69.  
  70. The beachball takes two colors which are used for the alternating 
  71. vertical stripes. In RGB mode, the colors are interpreted as cpack
  72. values (of the form 0xAABBGGRR); in color map mode the colors are
  73. interpreted as colormap indices.
  74.  
  75. Bug:
  76. For the cube, beam and torus, only one size may be active at one time.
  77. That is, everytime you call settorus, you change the shape of any torii
  78. you are currently displaying.
  79.  
  80. Commercial:
  81. This shapes library is brought to you by the letter f.
  82. ************************************************************/
  83.  
  84. #include <gl/gl.h>
  85. #include <gl/get.h>
  86. #include <gl/sphere.h>
  87. #include <math.h>
  88. #include "shapes.h"
  89.  
  90. /* three dimensional vector */
  91. typedef float vector[3];
  92.  
  93. /* useful vectors  for the cube, beam, letter f and axes */
  94. static vector front  = { 0.0,  0.0,  1.0};
  95. static vector back   = { 0.0,  0.0, -1.0};
  96. static vector top    = { 0.0,  1.0,  0.0};
  97. static vector bottom = { 0.0, -1.0,  0.0};
  98. static vector right  = { 1.0,  0.0,  0.0};
  99. static vector left   = {-1.0,  0.0,  0.0};
  100. static vector center = { 0.0,  0.0,  0.0};
  101.  
  102.  
  103. /************************************************************
  104. LETTER F
  105. ************************************************************/
  106.  
  107. /* default size for the letter f */
  108. #define F_SIZE 1.0
  109. #define F_DEPTH 1.0
  110.  
  111. /* array of letter f vertices */
  112. static vector f_point[20];
  113.  
  114. /* has the letter f been initialized */
  115. static Boolean letterf_initialized = FALSE;
  116.  
  117. /* initialize the letter f vertices */
  118. static void initletterf(void)
  119. {
  120.     float size = F_SIZE, depth = F_DEPTH;
  121.     int i;
  122.     
  123.     f_point[0][0] = f_point[10][0] = -0.3 * size;
  124.     f_point[0][1] = f_point[10][1] = -0.5 * size;
  125.     f_point[1][0] = f_point[11][0] = -0.3 * size;
  126.     f_point[1][1] = f_point[11][1] = 0.5 * size;
  127.     f_point[2][0] = f_point[12][0] = 0.3 * size;
  128.     f_point[2][1] = f_point[12][1] = 0.5 * size;
  129.     f_point[3][0] = f_point[13][0] = 0.3 * size;
  130.     f_point[3][1] = f_point[13][1] = 0.3 * size;
  131.     f_point[4][0] = f_point[14][0] = -0.1 * size;
  132.     f_point[4][1] = f_point[14][1] = 0.3 * size;
  133.     f_point[5][0] = f_point[15][0] = -0.1 * size;
  134.     f_point[5][1] = f_point[15][1] = 0.1 * size;
  135.     f_point[6][0] = f_point[16][0] = 0.1 * size;
  136.     f_point[6][1] = f_point[16][1] = 0.1 * size;
  137.     f_point[7][0] = f_point[17][0] = 0.1 * size;
  138.     f_point[7][1] = f_point[17][1] = -0.1 * size;
  139.     f_point[8][0] = f_point[18][0] = -0.1 * size;
  140.     f_point[8][1] = f_point[18][1] = -0.1 * size;
  141.     f_point[9][0] = f_point[19][0] = -0.1 * size;
  142.     f_point[9][1] = f_point[19][1] = -0.5 * size;
  143.     
  144.     /*    store z coordinates for vertices  */
  145.     for (i = 0; i < 10; i++)
  146.     {
  147.         f_point[i][2] = depth/2.0;
  148.         f_point[i+10][2] = -depth/2.0;
  149.     }
  150.  
  151.     letterf_initialized = TRUE;
  152. }
  153.  
  154.  
  155. /* wireframe letter f */
  156. void wletterf(void)
  157. {
  158.     int i;
  159.  
  160.     if (! letterf_initialized)
  161.         initletterf();
  162.  
  163.     /* draw front closedline */
  164.     bgnclosedline();
  165.         v3f(f_point[9]);
  166.         v3f(f_point[8]);
  167.         v3f(f_point[7]);
  168.         v3f(f_point[6]);
  169.         v3f(f_point[5]);
  170.         v3f(f_point[4]);
  171.         v3f(f_point[3]);
  172.         v3f(f_point[2]);
  173.         v3f(f_point[1]);
  174.         v3f(f_point[0]);
  175.     endclosedline();
  176.  
  177.     /* draw back closedline */
  178.     bgnclosedline();
  179.         v3f(f_point[10]);
  180.         v3f(f_point[11]);
  181.         v3f(f_point[12]);
  182.         v3f(f_point[13]);
  183.         v3f(f_point[14]);
  184.         v3f(f_point[15]);
  185.         v3f(f_point[16]);
  186.         v3f(f_point[17]);
  187.         v3f(f_point[18]);
  188.         v3f(f_point[19]);
  189.     endclosedline();
  190.     
  191.     /* draw first nine connecting closedlines */
  192.     for (i = 0; i < 9; i++)
  193.     {
  194.         bgnclosedline();
  195.             v3f(f_point[i+1]);
  196.             v3f(f_point[i+11]);
  197.             v3f(f_point[i+10]);
  198.             v3f(f_point[i]);
  199.         endclosedline();
  200.     }
  201.  
  202.     /* draw closed line at very bottom */
  203.     bgnclosedline();
  204.         v3f(f_point[0]);
  205.         v3f(f_point[10]);
  206.         v3f(f_point[19]);
  207.         v3f(f_point[9]);
  208.     endclosedline();
  209.     
  210. }
  211.  
  212.  
  213. /* filled letter f */
  214. void fletterf(void)
  215. {
  216.     if (! letterf_initialized)
  217.         initletterf();
  218.  
  219.     /* draw front face decomposed into convex polygons */
  220.     bgnpolygon();
  221.         n3f(front);
  222.         v3f(f_point[0]);
  223.         v3f(f_point[9]);
  224.         v3f(f_point[4]);
  225.         v3f(f_point[1]);
  226.     endpolygon();
  227.     bgnpolygon();
  228.         n3f(front);
  229.         v3f(f_point[1]);
  230.         v3f(f_point[4]);
  231.         v3f(f_point[3]);
  232.         v3f(f_point[2]);
  233.     endpolygon();
  234.     bgnpolygon();
  235.         n3f(front);
  236.         v3f(f_point[1]);
  237.         v3f(f_point[4]);
  238.         v3f(f_point[3]);
  239.         v3f(f_point[2]);
  240.     endpolygon();
  241.     bgnpolygon();
  242.         n3f(front);
  243.         v3f(f_point[8]);
  244.         v3f(f_point[7]);
  245.         v3f(f_point[6]);
  246.         v3f(f_point[5]);
  247.     endpolygon();
  248.     
  249.     /* draw back face decomposed into convex polygons */
  250.     bgnpolygon();
  251.         n3f(back);
  252.         v3f(f_point[11]);
  253.         v3f(f_point[14]);
  254.         v3f(f_point[19]);
  255.         v3f(f_point[10]);
  256.     endpolygon();
  257.     bgnpolygon();
  258.         n3f(back);
  259.         v3f(f_point[12]);
  260.         v3f(f_point[13]);
  261.         v3f(f_point[14]);
  262.         v3f(f_point[11]);
  263.     endpolygon();
  264.     bgnpolygon();
  265.         n3f(back);
  266.         v3f(f_point[12]);
  267.         v3f(f_point[13]);
  268.         v3f(f_point[14]);
  269.         v3f(f_point[11]);
  270.     endpolygon();
  271.     bgnpolygon();
  272.         n3f(back);
  273.         v3f(f_point[15]);
  274.         v3f(f_point[16]);
  275.         v3f(f_point[17]);
  276.         v3f(f_point[18]);
  277.     endpolygon();
  278.  
  279.     /* draw sides */
  280.     
  281.     bgnpolygon();
  282.         n3f(bottom);
  283.         v3f(f_point[0]);
  284.         v3f(f_point[10]);
  285.         v3f(f_point[19]);
  286.         v3f(f_point[9]);
  287.     endpolygon();
  288.     
  289.     bgnpolygon();
  290.         n3f(left);
  291.         v3f(f_point[0]);
  292.         v3f(f_point[1]);
  293.         v3f(f_point[11]);
  294.         v3f(f_point[10]);
  295.     endpolygon();
  296.     
  297.     bgnpolygon();
  298.         n3f(top);
  299.         v3f(f_point[1]);
  300.         v3f(f_point[2]);
  301.         v3f(f_point[12]);
  302.         v3f(f_point[11]);
  303.     endpolygon();
  304.  
  305.     bgnpolygon();
  306.         n3f(right);
  307.         v3f(f_point[2]);
  308.         v3f(f_point[3]);
  309.         v3f(f_point[13]);
  310.         v3f(f_point[12]);
  311.     endpolygon();
  312.  
  313.     bgnpolygon();
  314.         n3f(bottom);
  315.         v3f(f_point[3]);
  316.         v3f(f_point[4]);
  317.         v3f(f_point[14]);
  318.         v3f(f_point[13]);
  319.     endpolygon();
  320.  
  321.     bgnpolygon();
  322.         n3f(right);
  323.         v3f(f_point[4]);
  324.         v3f(f_point[5]);
  325.         v3f(f_point[15]);
  326.         v3f(f_point[14]);
  327.     endpolygon();
  328.  
  329.     bgnpolygon();
  330.         n3f(top);
  331.         v3f(f_point[5]);
  332.         v3f(f_point[6]);
  333.         v3f(f_point[16]);
  334.         v3f(f_point[15]);
  335.     endpolygon();
  336.  
  337.     bgnpolygon();
  338.         n3f(right);
  339.         v3f(f_point[6]);
  340.         v3f(f_point[7]);
  341.         v3f(f_point[17]);
  342.         v3f(f_point[16]);
  343.     endpolygon();
  344.  
  345.     bgnpolygon();
  346.         n3f(bottom);
  347.         v3f(f_point[7]);
  348.         v3f(f_point[8]);
  349.         v3f(f_point[18]);
  350.         v3f(f_point[17]);
  351.     endpolygon();
  352.  
  353.     bgnpolygon();
  354.         n3f(right);
  355.         v3f(f_point[8]);
  356.         v3f(f_point[9]);
  357.         v3f(f_point[19]);
  358.         v3f(f_point[18]);
  359.     endpolygon();
  360. }
  361.  
  362.  
  363. /************************************************************
  364. CUBE
  365. ************************************************************/
  366.  
  367. /* default cube size */
  368. #define CUBE_X 1.0
  369. #define CUBE_Y 1.0
  370. #define CUBE_Z 1.0
  371.  
  372. /* array for cube vertices */
  373. static vector cube_point[8];
  374.  
  375. /* has the cube been initialized */
  376. static Boolean cube_initialized = FALSE;
  377.  
  378. void setcube(float x, float y, float z)
  379. {
  380.     cube_point[1][0] = cube_point[2][0] = 
  381.     cube_point[5][0] = cube_point[6][0] = x/2.0;
  382.     
  383.     cube_point[0][0] = cube_point[3][0] = 
  384.     cube_point[4][0] = cube_point[7][0] = -x/2.0;
  385.     
  386.     cube_point[2][1] = cube_point[3][1] = 
  387.     cube_point[6][1] = cube_point[7][1] = y/2.0;
  388.     
  389.     cube_point[0][1] = cube_point[1][1] = 
  390.     cube_point[4][1] = cube_point[5][1] = -y/2.0;
  391.     
  392.     cube_point[0][2] = cube_point[1][2] = 
  393.     cube_point[2][2] = cube_point[3][2] = z/2.0;
  394.     
  395.     cube_point[4][2] = cube_point[5][2] = 
  396.     cube_point[6][2] = cube_point[7][2] = -z/2.0;
  397.  
  398.     cube_initialized = TRUE;
  399. }
  400.     
  401.  
  402. /* wireframe cube */
  403. void wcube(void)
  404. {
  405.     if (! cube_initialized)
  406.         setcube(CUBE_X, CUBE_Y, CUBE_Z);
  407.  
  408.     /* draw bottom facing closedline */
  409.     bgnclosedline();
  410.         v3f(cube_point[4]);
  411.         v3f(cube_point[5]);
  412.         v3f(cube_point[1]);
  413.         v3f(cube_point[0]);
  414.     endclosedline();
  415.  
  416.     /* draw left facing closedline */
  417.     bgnclosedline();
  418.         v3f(cube_point[3]);
  419.         v3f(cube_point[7]);
  420.         v3f(cube_point[4]);
  421.         v3f(cube_point[0]);
  422.     endclosedline();
  423.  
  424.     /* draw right facing closedline */
  425.     bgnclosedline();
  426.         v3f(cube_point[5]);
  427.         v3f(cube_point[6]);
  428.         v3f(cube_point[2]);
  429.         v3f(cube_point[1]);
  430.     endclosedline();
  431.  
  432.     /* draw top facing closedline */
  433.     bgnclosedline();
  434.         v3f(cube_point[6]);
  435.         v3f(cube_point[7]);
  436.         v3f(cube_point[3]);
  437.         v3f(cube_point[2]);
  438.     endclosedline();
  439.  
  440.     /* draw front facing closedline */   
  441.     bgnclosedline();
  442.         v3f(cube_point[1]);
  443.         v3f(cube_point[2]);
  444.         v3f(cube_point[3]);
  445.         v3f(cube_point[0]);
  446.     endclosedline();
  447.  
  448.     /* draw back facing closedline */
  449.     bgnclosedline();
  450.         v3f(cube_point[6]);
  451.         v3f(cube_point[5]);
  452.         v3f(cube_point[4]);
  453.         v3f(cube_point[7]);
  454.     endclosedline();
  455. }
  456.  
  457.  
  458. /* filled cube */
  459. void fcube(void)
  460. {
  461.     if (! cube_initialized)
  462.         setcube(CUBE_X, CUBE_Y, CUBE_Z);
  463.  
  464.     /* draw bottom facing polygon */
  465.     bgnpolygon();
  466.         n3f(bottom);
  467.         v3f(cube_point[4]);
  468.         v3f(cube_point[5]);
  469.         v3f(cube_point[1]);
  470.         v3f(cube_point[0]);
  471.     endpolygon();
  472.  
  473.     /* draw left facing polygon */
  474.     bgnpolygon();
  475.         n3f(left);
  476.         v3f(cube_point[3]);
  477.         v3f(cube_point[7]);
  478.         v3f(cube_point[4]);
  479.         v3f(cube_point[0]);
  480.     endpolygon();
  481.  
  482.     /* draw right facing polygon */
  483.     bgnpolygon();
  484.         n3f(right);
  485.         v3f(cube_point[5]);
  486.         v3f(cube_point[6]);
  487.         v3f(cube_point[2]);
  488.         v3f(cube_point[1]);
  489.     endpolygon();
  490.  
  491.     /* draw top facing polygon */
  492.     bgnpolygon();
  493.         n3f(top);
  494.         v3f(cube_point[6]);
  495.         v3f(cube_point[7]);
  496.         v3f(cube_point[3]);
  497.         v3f(cube_point[2]);
  498.     endpolygon();
  499.  
  500.     /* draw front facing polygon */   
  501.     bgnpolygon();
  502.         n3f(front);
  503.         v3f(cube_point[1]);
  504.         v3f(cube_point[2]);
  505.         v3f(cube_point[3]);
  506.         v3f(cube_point[0]);
  507.     endpolygon();
  508.  
  509.     /* draw back facing polygon */
  510.     bgnpolygon();
  511.         n3f(back);
  512.         v3f(cube_point[6]);
  513.         v3f(cube_point[5]);
  514.         v3f(cube_point[4]);
  515.         v3f(cube_point[7]);
  516.     endpolygon();
  517. }
  518.  
  519.  
  520. /************************************************************
  521. BEAM
  522. ************************************************************/
  523.  
  524. /* default beam size */
  525. #define BEAM_X 1.0
  526. #define BEAM_Y 0.2
  527. #define BEAM_Z 0.5
  528.  
  529. /* array for beam vertices */
  530. static vector beam_point[8];
  531.  
  532. /* has the beam been initialized */
  533. static Boolean beam_initialized = FALSE;
  534.  
  535.  
  536. void setbeam(float x, float y, float z)
  537. {
  538.     beam_point[1][0] = beam_point[2][0] = 
  539.     beam_point[5][0] = beam_point[6][0] = x;
  540.     
  541.     beam_point[0][0] = beam_point[3][0] = 
  542.     beam_point[4][0] = beam_point[7][0] = 0.0;
  543.     
  544.     beam_point[2][1] = beam_point[3][1] = 
  545.     beam_point[6][1] = beam_point[7][1] = y/2.0;
  546.     
  547.     beam_point[0][1] = beam_point[1][1] = 
  548.     beam_point[4][1] = beam_point[5][1] = -y/2.0;
  549.     
  550.     beam_point[0][2] = beam_point[1][2] = 
  551.     beam_point[2][2] = beam_point[3][2] = z/2.0;
  552.     
  553.     beam_point[4][2] = beam_point[5][2] = 
  554.     beam_point[6][2] = beam_point[7][2] = -z/2.0;
  555.  
  556.     beam_initialized = TRUE;
  557. }    
  558.  
  559.  
  560. /* wireframe beam */
  561. void wbeam(void)
  562. {
  563.     if (! beam_initialized)
  564.         setbeam(BEAM_X, BEAM_Y, BEAM_Z);
  565.     
  566.     /* draw bottom facing closedline */
  567.     bgnclosedline();
  568.         v3f(beam_point[4]);
  569.         v3f(beam_point[5]);
  570.         v3f(beam_point[1]);
  571.         v3f(beam_point[0]);
  572.     endclosedline();
  573.  
  574.     /* draw left facing closedline */
  575.     bgnclosedline();
  576.         v3f(beam_point[3]);
  577.         v3f(beam_point[7]);
  578.         v3f(beam_point[4]);
  579.         v3f(beam_point[0]);
  580.     endclosedline();
  581.  
  582.     /* draw right facing closedline */
  583.     bgnclosedline();
  584.         v3f(beam_point[5]);
  585.         v3f(beam_point[6]);
  586.         v3f(beam_point[2]);
  587.         v3f(beam_point[1]);
  588.     endclosedline();
  589.  
  590.     /* draw top facing closedline */
  591.     bgnclosedline();
  592.         v3f(beam_point[6]);
  593.         v3f(beam_point[7]);
  594.         v3f(beam_point[3]);
  595.         v3f(beam_point[2]);
  596.     endclosedline();
  597.  
  598.     /* draw front facing closedline */   
  599.     bgnclosedline();
  600.         v3f(beam_point[1]);
  601.         v3f(beam_point[2]);
  602.         v3f(beam_point[3]);
  603.         v3f(beam_point[0]);
  604.     endclosedline();
  605.  
  606.     /* draw back facing closedline */
  607.     bgnclosedline();
  608.         v3f(beam_point[6]);
  609.         v3f(beam_point[5]);
  610.         v3f(beam_point[4]);
  611.         v3f(beam_point[7]);
  612.     endclosedline();
  613. }
  614.  
  615.         
  616. /* filled beam */
  617. void fbeam(void)
  618. {
  619.     if (! beam_initialized)
  620.         setbeam(BEAM_X, BEAM_Y, BEAM_Z);
  621.     
  622.     /* draw bottom facing polygon */
  623.     bgnpolygon();
  624.         n3f(bottom);
  625.         v3f(beam_point[4]);
  626.         v3f(beam_point[5]);
  627.         v3f(beam_point[1]);
  628.         v3f(beam_point[0]);
  629.     endpolygon();
  630.  
  631.     /* draw left facing polygon */
  632.     bgnpolygon();
  633.         n3f(left);
  634.         v3f(beam_point[3]);
  635.         v3f(beam_point[7]);
  636.         v3f(beam_point[4]);
  637.         v3f(beam_point[0]);
  638.     endpolygon();
  639.  
  640.     /* draw right facing polygon */
  641.     bgnpolygon();
  642.         n3f(right);
  643.         v3f(beam_point[5]);
  644.         v3f(beam_point[6]);
  645.         v3f(beam_point[2]);
  646.         v3f(beam_point[1]);
  647.     endpolygon();
  648.  
  649.     /* draw top facing polygon */
  650.     bgnpolygon();
  651.         n3f(top);
  652.         v3f(beam_point[6]);
  653.         v3f(beam_point[7]);
  654.         v3f(beam_point[3]);
  655.         v3f(beam_point[2]);
  656.     endpolygon();
  657.  
  658.     /* draw front facing polygon */   
  659.     bgnpolygon();
  660.         n3f(front);
  661.         v3f(beam_point[1]);
  662.         v3f(beam_point[2]);
  663.         v3f(beam_point[3]);
  664.         v3f(beam_point[0]);
  665.     endpolygon();
  666.  
  667.     /* draw back facing polygon */
  668.     bgnpolygon();
  669.         n3f(back);
  670.         v3f(beam_point[6]);
  671.         v3f(beam_point[5]);
  672.         v3f(beam_point[4]);
  673.         v3f(beam_point[7]);
  674.     endpolygon();
  675. }
  676.  
  677.  
  678. /************************************************************
  679. TETRAHEDRON
  680. ************************************************************/
  681.  
  682. /* default tetrahedron size */
  683. #define TETRA_BASE 1.0
  684. #define TETRA_HEIGHT 1.0
  685.  
  686. /* arrays for tetrahedron vertices and normals */
  687. static vector tetra_point[4];
  688. static vector tetra_norm[4];
  689.  
  690. /* has the tetrahedron been initialized yet */
  691. static Boolean tetra_initialized = FALSE;
  692.     
  693. static void inittetra(void)
  694. {
  695.     float b = TETRA_BASE, h = TETRA_HEIGHT;
  696.     
  697.     tetra_point[0][0] = 0.0;        
  698.     tetra_point[0][1] = -h/2.0;
  699.     tetra_point[0][2] = b/fsqrt(3.0);
  700.     tetra_point[1][0] = -b/2.0;    
  701.     tetra_point[1][1] = -h/2.0; 
  702.     tetra_point[1][2] = -b/(2.0*fsqrt(3.0));
  703.     tetra_point[2][0] = b/2.0;    
  704.     tetra_point[2][1] = -h/2.0;
  705.     tetra_point[2][2] = -b/(2.0*fsqrt(3.0));
  706.     tetra_point[3][0] = 0.0;        
  707.     tetra_point[3][1] = h/2.0;  
  708.     tetra_point[3][2] = 0.0;
  709.  
  710.     tetra_norm[0][0] = 0.0;        
  711.     tetra_norm[0][1] = h/2.0;
  712.     tetra_norm[0][2] = -b/fsqrt(3.0);
  713.     tetra_norm[1][0] = b/2.0;    
  714.     tetra_norm[1][1] = h/2.0; 
  715.     tetra_norm[1][2] = b/(2.0*fsqrt(3.0));
  716.     tetra_norm[2][0] = -b/2.0;    
  717.     tetra_norm[2][1] = h/2.0;
  718.     tetra_norm[2][2] = b/(2.0*fsqrt(3.0));
  719.     tetra_norm[3][0] = 0.0;        
  720.     tetra_norm[3][1] = -h/2.0;  
  721.     tetra_norm[3][2] = 0.0;
  722.  
  723.     tetra_initialized = TRUE;
  724. }
  725.  
  726.  
  727. /* wireframe tetrahedron */
  728. void wtetra(void)
  729. {
  730.     if (! tetra_initialized)
  731.         inittetra();
  732.  
  733.     bgnclosedline();
  734.         v3f(tetra_point[0]);
  735.         v3f(tetra_point[1]);
  736.         v3f(tetra_point[2]);
  737.     endclosedline();
  738.     
  739.     bgnclosedline();
  740.         v3f(tetra_point[0]);
  741.         v3f(tetra_point[3]);
  742.         v3f(tetra_point[1]);
  743.     endclosedline();
  744.  
  745.     bgnclosedline();
  746.         v3f(tetra_point[0]);
  747.         v3f(tetra_point[2]);
  748.         v3f(tetra_point[3]);
  749.     endclosedline();
  750.  
  751.     bgnclosedline();
  752.         v3f(tetra_point[1]);
  753.         v3f(tetra_point[3]);
  754.         v3f(tetra_point[2]);
  755.     endclosedline();
  756. }
  757.  
  758.  
  759. /* filled tetrahedron */
  760. void ftetra(void)
  761. {
  762.     if (! tetra_initialized)
  763.         inittetra();
  764.  
  765.     bgnpolygon();
  766.         n3f(tetra_norm[3]);
  767.         v3f(tetra_point[0]);
  768.         v3f(tetra_point[1]);
  769.         v3f(tetra_point[2]);
  770.     endpolygon();
  771.     
  772.     bgnpolygon();
  773.         n3f(tetra_norm[2]);
  774.         v3f(tetra_point[0]);
  775.         v3f(tetra_point[3]);
  776.         v3f(tetra_point[1]);
  777.     endpolygon();
  778.  
  779.     bgnpolygon();
  780.         n3f(tetra_norm[1]);
  781.         v3f(tetra_point[0]);
  782.         v3f(tetra_point[2]);
  783.         v3f(tetra_point[3]);
  784.     endpolygon();
  785.  
  786.     bgnpolygon();
  787.         n3f(tetra_norm[0]);
  788.         v3f(tetra_point[1]);
  789.         v3f(tetra_point[3]);
  790.         v3f(tetra_point[2]);
  791.     endpolygon();
  792. }
  793.  
  794.  
  795. /************************************************************
  796. OCTAHEDRON
  797. ************************************************************/
  798.  
  799. #define ONE_OVER_SQRT3 0.57735
  800.  
  801. /* unit vectors for the octahedron */
  802. static vector oct_ppp = { ONE_OVER_SQRT3, ONE_OVER_SQRT3, ONE_OVER_SQRT3};
  803. static vector oct_npp = {-ONE_OVER_SQRT3, ONE_OVER_SQRT3, ONE_OVER_SQRT3};
  804. static vector oct_pnp = { ONE_OVER_SQRT3,-ONE_OVER_SQRT3, ONE_OVER_SQRT3};
  805. static vector oct_nnp = {-ONE_OVER_SQRT3,-ONE_OVER_SQRT3, ONE_OVER_SQRT3};
  806. static vector oct_ppn = { ONE_OVER_SQRT3, ONE_OVER_SQRT3,-ONE_OVER_SQRT3};
  807. static vector oct_npn = {-ONE_OVER_SQRT3, ONE_OVER_SQRT3,-ONE_OVER_SQRT3};
  808. static vector oct_pnn = { ONE_OVER_SQRT3,-ONE_OVER_SQRT3,-ONE_OVER_SQRT3};
  809. static vector oct_nnn = {-ONE_OVER_SQRT3,-ONE_OVER_SQRT3,-ONE_OVER_SQRT3};
  810.  
  811. /* wireframe octahedron */
  812. void wocta(void)
  813. {
  814.     bgnclosedline();
  815.         v3f(top);
  816.         v3f(back);
  817.         v3f(bottom);
  818.         v3f(front);
  819.     endclosedline();
  820.  
  821.     bgnclosedline();
  822.         v3f(top);
  823.         v3f(right);
  824.         v3f(bottom);
  825.         v3f(left);
  826.     endclosedline();
  827.  
  828.     bgnclosedline();
  829.         v3f(right);
  830.         v3f(top);
  831.         v3f(left);
  832.         v3f(bottom);
  833.     endclosedline();
  834.  
  835.     bgnclosedline();
  836.         v3f(right);
  837.         v3f(back);
  838.         v3f(left);
  839.         v3f(front);
  840.     endclosedline();
  841. }
  842.  
  843.  
  844. /* filled octahedron */
  845. void focta(void)
  846. {
  847.     bgnpolygon();
  848.         n3f(oct_ppp);
  849.         v3f(front);
  850.         v3f(right);
  851.         v3f(top);
  852.     endpolygon();
  853.     
  854.     bgnpolygon();
  855.         n3f(oct_npp);
  856.         v3f(left);
  857.         v3f(front);
  858.         v3f(top);
  859.     endpolygon();
  860.     
  861.     bgnpolygon();
  862.         n3f(oct_pnp);
  863.         v3f(right);
  864.         v3f(front);
  865.         v3f(bottom);
  866.     endpolygon();
  867.     
  868.     bgnpolygon();
  869.         n3f(oct_nnp);
  870.         v3f(left);
  871.         v3f(bottom);
  872.         v3f(front);
  873.     endpolygon();
  874.     
  875.     bgnpolygon();
  876.         n3f(oct_ppn);
  877.         v3f(top);
  878.         v3f(right);
  879.         v3f(back);
  880.     endpolygon();
  881.     
  882.     bgnpolygon();
  883.         n3f(oct_npn);
  884.         v3f(top);
  885.         v3f(back);
  886.         v3f(left);
  887.     endpolygon();
  888.     
  889.     bgnpolygon();
  890.         n3f(oct_pnn);
  891.         v3f(right);
  892.         v3f(bottom);
  893.         v3f(back);
  894.     endpolygon();
  895.     
  896.     bgnpolygon();
  897.         n3f(oct_nnn);
  898.         v3f(left);
  899.         v3f(back);
  900.         v3f(bottom);
  901.     endpolygon();
  902. }
  903.  
  904.  
  905. /************************************************************
  906. DODECAHEDRON
  907. ************************************************************/
  908.  
  909. /* unique vertices of the dodecahedron */
  910. static vector dodecdata[] = 
  911. {
  912.     {-0.7310437803862881,-0.5818932866609501,-0.3563357884039183 },
  913.     {-0.9866414845543432,-0.113148838743958 , 0.1172003466176425 },
  914.     {-0.8315553684216557, 0.543115689197534 ,-0.116365877286309  },
  915.     {-0.4801091733003869, 0.4799650251592924,-0.7342538773044778 },
  916.     {-0.4179895956313016,-0.2153287595699611,-0.8825634386524534 },
  917.     { 0.2300325072865204, 0.9726753463107327, 0.03142795365232666},
  918.     { 0.1759882159320658, 0.7454474934509961,-0.6429122664568439 },
  919.     {-0.3926636729909752, 0.8476274142770002, 0.3568515188132501 },
  920.     { 0.6435982800768732, 0.214230897543234 ,-0.7347696077138133 },
  921.     { 0.2764998039674345,-0.3795614824074853,-0.8828821775744499 },
  922.     { 0.3926636729909749,-0.8476274142770016,-0.3568515188132467 },
  923.     {-0.2300325072865201,-0.9726753463107329,-0.03142795365232794},
  924.     {-0.1759882159320652,-0.7454474934509932, 0.6429122664568472 },
  925.     {-0.6435982800768731,-0.2142308975432367, 0.7347696077138126 },
  926.     {-0.2764998039674331, 0.3795614824074883, 0.882882177574449  },
  927.     { 0.4801091733003879,-0.479965025159286 , 0.7342538773044812 },
  928.     { 0.4179895956313024, 0.2153287595699666, 0.8825634386524518 },
  929.     { 0.8315553684216548,-0.5431156891975345, 0.1163658772863122 },
  930.     { 0.9866414845543432, 0.1131488387439548,-0.1172003466176457 },
  931.     { 0.7310437803862896, 0.5818932866609513, 0.3563357884039132 },
  932. };
  933.  
  934.  
  935. /* vertex indices for each facet of the dodecahedron */
  936. static int dodecfacets[][5] = 
  937.     { 0 , 1 , 2 , 3 , 4 },
  938.     { 5 , 6 , 3 , 2 , 7 },
  939.     { 8 , 9 , 4 , 3 , 6 },
  940.     { 10 , 11 , 0 , 4 , 9 },
  941.     { 12 , 13 , 1 , 0 , 11 },
  942.     { 14 , 7 , 2 , 1 , 13 },
  943.     { 13 , 12 , 15 , 16 , 14 },
  944.     { 11 , 10 , 17 , 15 , 12 },
  945.     { 9 , 8 , 18 , 17 , 10 },
  946.     { 6 , 5 , 19 , 18 , 8 },
  947.     { 7 , 14 , 16 , 19 , 5 },
  948.     { 19 , 16 , 15 , 17 , 18 }
  949. };
  950.  
  951.  
  952. /* wireframe dodecahedron */
  953. void wdodeca(void)
  954. {
  955.  
  956.     int facet;
  957.     int vertex;
  958.  
  959.     for (facet=0; facet < 12; facet++)
  960.     {
  961.         bgnclosedline();
  962.             for (vertex = 0; vertex < 5; vertex++)
  963.                 v3f(dodecdata[dodecfacets[facet][vertex]]);
  964.         endclosedline();
  965.     }
  966. }
  967.  
  968.  
  969. /* filled dodecahedron */
  970. void fdodeca(void)
  971. {
  972.     int facet, vertex, c;
  973.     static vector norm[12];
  974.     static Boolean normals_initialized = FALSE;
  975.  
  976.     /* compute the facet normal as the average of the vertex normals */
  977.     if (! normals_initialized)
  978.     {
  979.         for (facet = 0; facet < 12; facet++)
  980.         {
  981.             norm[facet][0] = norm[facet][1] = norm[facet][2] = 0.0;
  982.             
  983.             for (vertex = 0; vertex < 5; vertex++)
  984.                 for (c = 0; c < 3; c++)
  985.                     norm[facet][c] += dodecdata[dodecfacets[facet][vertex]][c];
  986.                     
  987.             norm[facet][0] /= 5.0;
  988.             norm[facet][1] /= 5.0;
  989.             norm[facet][2] /= 5.0;
  990.         }
  991.  
  992.         normals_initialized = TRUE;
  993.     }    
  994.  
  995.     for (facet = 0; facet < 12; facet++)
  996.     {
  997.         bgnpolygon();
  998.             n3f(norm[facet]);
  999.             for (vertex = 0; vertex < 5; vertex++)
  1000.                 v3f(dodecdata[dodecfacets[facet][vertex]]);
  1001.         endpolygon();
  1002.     }
  1003. }
  1004.  
  1005.  
  1006. /************************************************************
  1007. ICOSAHEDRON
  1008. ************************************************************/
  1009.  
  1010. /* unique vertices of the icosahedron */
  1011. static float icosadata[][3] =
  1012. {
  1013.     { 0.000000,  0.000000, -1.000000},
  1014.     { 0.000000,  0.894427, -0.447214},
  1015.     { 0.850651,  0.276393, -0.447214},
  1016.     { 0.525731, -0.723607, -0.447214},
  1017.     {-0.525731, -0.723607, -0.447214},
  1018.     {-0.850651,  0.276393, -0.447214},
  1019.     { 0.525731,  0.723607,  0.447214},
  1020.     { 0.850651, -0.276393,  0.447214},
  1021.     { 0.000000, -0.894427,  0.447214},
  1022.     {-0.850651, -0.276393,  0.447214},
  1023.     {-0.525731,  0.723607,  0.447214},
  1024.     { 0.000000,  0.000000,  1.000000}
  1025. };
  1026.  
  1027. /* vertex indices for each facet of the icosahedron */
  1028. static int icosafacets[][3] =
  1029. {
  1030.      1, 2, 0,
  1031.      2, 3, 0,
  1032.      3, 4, 0,
  1033.      4, 5, 0,
  1034.      5, 1, 0,
  1035.     10, 6, 1,
  1036.      6, 2, 1,
  1037.      6, 7, 2,
  1038.      7, 3, 2,
  1039.      7, 8, 3,
  1040.      8, 4, 3,
  1041.      8, 9, 4,
  1042.      9, 5, 4,
  1043.      9,10, 5,
  1044.     10, 1, 5,
  1045.     11, 6,10,
  1046.     11, 7, 6,
  1047.     11, 8, 7,
  1048.     11, 9, 8,
  1049.     11,10, 9,
  1050. };
  1051.  
  1052.  
  1053. /* wireframe icosahedron */
  1054. void wicosa(void)
  1055. {
  1056.     int facet, vertex;
  1057.     
  1058.     for (facet = 0; facet < 20; facet++)
  1059.     {
  1060.         bgnclosedline();
  1061.             for (vertex = 0; vertex < 3; vertex++)
  1062.                 v3f(icosadata[icosafacets[facet][vertex]]);
  1063.         endclosedline();
  1064.     }
  1065. }
  1066.  
  1067.  
  1068. /* filled icosahedron */
  1069. void ficosa(void)
  1070. {
  1071.     int facet, vertex, c;
  1072.     static vector norm[20];
  1073.     static Boolean normals_initialized = FALSE;
  1074.  
  1075.     /* compute the facet normal as the average of the vertex normals */
  1076.     if (! normals_initialized)
  1077.     {
  1078.         for (facet = 0; facet < 20; facet++)
  1079.         {
  1080.             norm[facet][0] = norm[facet][1] = norm[facet][2] = 0.0;
  1081.             
  1082.             for (vertex = 0; vertex < 3; vertex++)
  1083.                 for (c = 0; c < 3; c++)
  1084.                     norm[facet][c] += icosadata[icosafacets[facet][vertex]][c];
  1085.                     
  1086.             norm[facet][0] /= 3.0;
  1087.             norm[facet][1] /= 3.0;
  1088.             norm[facet][2] /= 3.0;
  1089.         }
  1090.         
  1091.         normals_initialized = TRUE;
  1092.     }
  1093.  
  1094.     for (facet = 0; facet < 20; facet++)
  1095.     {
  1096.         bgnpolygon();
  1097.             n3f(norm[facet]);
  1098.             for (vertex = 0; vertex < 3; vertex++)
  1099.                 v3f(icosadata[icosafacets[facet][vertex]]);
  1100.         endpolygon();
  1101.     }
  1102. }
  1103.  
  1104.  
  1105. /************************************************************
  1106. CONE
  1107. ************************************************************/
  1108.  
  1109. /* number of facets around the cone */
  1110. #define CONE_FACETS 30
  1111.  
  1112. /* has the cone been initialized */
  1113. static Boolean cone_initialized = FALSE;
  1114.  
  1115. /* arrays for cone vertices and normals */
  1116. static vector cone_point[CONE_FACETS];
  1117. static vector cone_norm[CONE_FACETS];
  1118.  
  1119.  
  1120. static void initcone(
  1121.     vector point[CONE_FACETS],
  1122.     vector norm[CONE_FACETS])
  1123. {
  1124.     int i;
  1125.     int facets = CONE_FACETS;
  1126.     float theta,nx,ny,nz,l;
  1127.     
  1128.     for (i = 0; i < facets; i++)
  1129.     {
  1130.         theta = 2.0*M_PI*(float)i/(float)facets;
  1131.  
  1132.         point[i][0] = fcos(theta);
  1133.         point[i][1] = 0.0;
  1134.         point[i][2] = fsin(theta);
  1135.  
  1136.         nx = fcos(theta);
  1137.         ny = fcos(M_PI/4.0)*fsin(M_PI/4.0);
  1138.         nz = fsin(theta);
  1139.         l = fsqrt(nx*nx + ny*ny + nz*nz);
  1140.  
  1141.         norm[i][0] = nx/l;
  1142.         norm[i][1] = ny/l;
  1143.         norm[i][2] = nz/l;
  1144.     }
  1145. }
  1146.  
  1147.  
  1148. /* 
  1149. wireframe cone of radius 1.0 and height 1.0 with the origin at
  1150. the center of the base
  1151. */
  1152. void wcone(void)
  1153. {
  1154.     int i, facets = CONE_FACETS;
  1155.     
  1156.     if (! cone_initialized)
  1157.     {
  1158.         initcone(cone_point, cone_norm);
  1159.         cone_initialized = TRUE;
  1160.     }
  1161.  
  1162.     for (i = 0; i < facets-1; i++)
  1163.     {
  1164.         bgnclosedline();
  1165.             v3f(top);
  1166.             v3f(cone_point[i]);
  1167.             v3f(cone_point[(i+1)%facets]);
  1168.         endclosedline();
  1169.     }
  1170.     bgnclosedline();
  1171.         v3f(top);
  1172.         v3f(cone_point[facets - 1]);
  1173.         v3f(cone_point[0]);
  1174.     endclosedline();
  1175. }
  1176.  
  1177.  
  1178.  
  1179. /* 
  1180. filled cone of radius 1.0 and height 1.0 with the origin at
  1181. the center of the base
  1182. */
  1183. void fcone(void)
  1184. {
  1185.     int i, facets = CONE_FACETS;
  1186.     float top_norm[3];
  1187.  
  1188.     if (! cone_initialized)
  1189.     {
  1190.         initcone(cone_point, cone_norm);
  1191.         cone_initialized = TRUE;
  1192.     }
  1193.  
  1194.     bgntmesh();
  1195.         n3f(cone_norm[0]);
  1196.         v3f(cone_point[0]);
  1197.     
  1198.         for (i = 1; i <= facets; i++)
  1199.         {
  1200.             n3f(cone_norm[i%facets]);
  1201.             v3f(top);
  1202.             n3f(cone_norm[i%facets]);
  1203.             v3f(cone_point[i%facets]);
  1204.         }
  1205.     endtmesh();
  1206. }
  1207.  
  1208.  
  1209. /************************************************************
  1210. CYLINDER
  1211. ************************************************************/
  1212.  
  1213. /* number of polygons around the cross section of the cylinder */
  1214. #define CYL_NUMC 20
  1215.  
  1216. /* number of polygons down the length of the cylinder */
  1217. #define CYL_NUML 10
  1218.  
  1219. /* arrays for torus vertices and normals */
  1220. static vector cyl_point[CYL_NUMC][CYL_NUML+1];
  1221. static vector cyl_norm[CYL_NUMC][CYL_NUML+1];
  1222.  
  1223. /* has the cylinder been initialized */
  1224. static Boolean cylinder_initialized = FALSE;
  1225.  
  1226.  
  1227. /* initialize a cylinder */
  1228. static void initcylinder(
  1229.     vector point[CYL_NUMC][CYL_NUML+1],    /* array of vertex data */
  1230.     vector norm[CYL_NUMC][CYL_NUML+1])    /* array of normal data */
  1231. {
  1232.     int i,j;
  1233.     float theta,nx,ny;
  1234.     int numc = CYL_NUMC, numl = CYL_NUML;
  1235.     
  1236.     for (i = 0; i < numc; i++)
  1237.     {
  1238.         theta = 2.0*M_PI*(float)i/(float)numc;
  1239.  
  1240.         nx = fcos(theta);
  1241.         ny = fsin(theta);
  1242.         
  1243.         for (j = 0; j <= numl; j++)
  1244.         {
  1245.             point[i][j][0] = nx;
  1246.             point[i][j][1] = ny;
  1247.             point[i][j][2] =(float)j/(float)numl - .5;
  1248.  
  1249.             norm[i][j][0] = nx;
  1250.             norm[i][j][1] = ny;
  1251.             norm[i][j][2] = 0.0;
  1252.         }
  1253.     }
  1254. }
  1255.  
  1256.  
  1257. /* wireframe cylinder */
  1258. void wcylinder(void)
  1259. {
  1260.     int i,j;
  1261.     int numc = CYL_NUMC, numl = CYL_NUML;
  1262.  
  1263.     if (! cylinder_initialized)
  1264.     {
  1265.         initcylinder(cyl_point,cyl_norm);
  1266.         cylinder_initialized = TRUE;
  1267.     }
  1268.     
  1269.     for (i = 0; i < numl; i++)
  1270.         for (j = 0; j < numc; j++)
  1271.         {
  1272.             bgnclosedline();
  1273.                 v3f(cyl_point[j][i]);
  1274.                 v3f(cyl_point[(j+1)%numc][i]);
  1275.                 v3f(cyl_point[j][i+1]);
  1276.             endclosedline();
  1277.             
  1278.             bgnclosedline();
  1279.                 v3f(cyl_point[(j+1)%numc][i]);
  1280.                 v3f(cyl_point[j][i+1]);
  1281.                 v3f(cyl_point[(j+1)%numc][i+1]);
  1282.             endclosedline();
  1283.         }
  1284. }
  1285.  
  1286.  
  1287. /* filled cylinder */
  1288. void fcylinder(void)
  1289. {
  1290.     int i,j;
  1291.     int numc = CYL_NUMC, numl = CYL_NUML;
  1292.  
  1293.     if (! cylinder_initialized)
  1294.     {
  1295.         initcylinder(cyl_point,cyl_norm);
  1296.         cylinder_initialized = TRUE;
  1297.     }
  1298.  
  1299.     for (i = 0; i < numc; i++)
  1300.     {
  1301.         bgntmesh();
  1302.             n3f(cyl_norm[i][0]);
  1303.             v3f(cyl_point[i][0]);
  1304.             for (j = 0; j < numl; j++)
  1305.             {
  1306.                     n3f(cyl_norm[(i+1)%numc][j]);
  1307.                     v3f(cyl_point[(i+1)%numc][j]);
  1308.                     n3f(cyl_norm[i][j+1]);
  1309.                     v3f(cyl_point[i][j+1]);
  1310.             }
  1311.             n3f(cyl_norm[(i+1)%numc][numl]);
  1312.             v3f(cyl_point[(i+1)%numc][numl]);
  1313.         endtmesh();
  1314.     }
  1315. }
  1316.  
  1317. /* filled, closed cylinder */
  1318. void fclocylinder(void)
  1319. {
  1320.     int i,j;
  1321.     int numc = CYL_NUMC, numl = CYL_NUML;
  1322.  
  1323.     if (! cylinder_initialized)
  1324.     {
  1325.         initcylinder(cyl_point,cyl_norm);
  1326.         cylinder_initialized = TRUE;
  1327.     }
  1328.  
  1329.     for (i = 0; i < numc; i++)
  1330.     {
  1331.         bgntmesh();
  1332.             n3f(cyl_norm[i][0]);
  1333.             v3f(cyl_point[i][0]);
  1334.             for (j = 0; j < numl; j++)
  1335.             {
  1336.                     n3f(cyl_norm[(i+1)%numc][j]);
  1337.                     v3f(cyl_point[(i+1)%numc][j]);
  1338.                     n3f(cyl_norm[i][j+1]);
  1339.                     v3f(cyl_point[i][j+1]);
  1340.             }
  1341.             n3f(cyl_norm[(i+1)%numc][numl]);
  1342.             v3f(cyl_point[(i+1)%numc][numl]);
  1343.         endtmesh();
  1344.     }
  1345.  
  1346.     bgntmesh();
  1347.         n3f(back);
  1348.         v3f(cyl_point[numc-1][0]);
  1349.         for (i = numc-2; i >= 0; i--)
  1350.         {
  1351.             v3f(cyl_point[i][0]);
  1352.             swaptmesh();
  1353.         }
  1354.     endtmesh();
  1355.  
  1356.     bgntmesh();
  1357.         n3f(front);
  1358.         v3f(cyl_point[0][numl]);
  1359.         for (i = 1; i < numc; i++)
  1360.         {
  1361.             v3f(cyl_point[i][numl]);
  1362.             swaptmesh();
  1363.         }
  1364.     endtmesh();
  1365. }
  1366.  
  1367.  
  1368. /************************************************************
  1369. TORUS
  1370. ************************************************************/
  1371.  
  1372. /* number of polygons around the cross section of the torus */
  1373. #define TORUS_NUMC 10
  1374.  
  1375. /* number of polygons around the outside of the torus */
  1376. #define TORUS_NUMT 20
  1377.  
  1378. /* default torus cross sectional radius */
  1379. #define TORUS_RAD_XC 0.3
  1380.  
  1381. /* default torus radius */
  1382. #define TORUS_RAD 1.0
  1383.  
  1384. /* arrays for torus vertices and normals */
  1385. static vector torus_point[TORUS_NUMC][TORUS_NUMT];
  1386. static vector torus_norm[TORUS_NUMC][TORUS_NUMT];
  1387.  
  1388. /* has the torus been initialized yet */
  1389. static Boolean torus_initialized = FALSE;
  1390.  
  1391.  
  1392. /* initalize data for a torus */
  1393. static void inittorus(
  1394.     float rc,    /* radius of the cross section */
  1395.     float rt,    /* radius of the torus */
  1396.     vector point[TORUS_NUMC][TORUS_NUMT], /* array of vertices */
  1397.     vector norm[TORUS_NUMC][TORUS_NUMT])  /* array of normals */
  1398. {
  1399.     int i, j;
  1400.     int numc = TORUS_NUMC, numt = TORUS_NUMT;
  1401.     float twopi, fi, fj, xc, yc, nx, ny, nz, n;
  1402.  
  1403.     twopi = 2.0 * M_PI;
  1404.  
  1405.     /* go around cross section */
  1406.     for (i = 0; i < numc; i++)
  1407.     {        
  1408.       fi =(float) i;
  1409.       
  1410.       /* go around top view     */
  1411.       for (j = 0; j < numt; j++)
  1412.         {    
  1413.             fj =(float) j;
  1414.  
  1415.             point[i][j][0] = (rt + rc*fcos(twopi*fi/numc))*fcos(twopi*fj/numt);
  1416.             point[i][j][1] = (rt + rc*fcos(twopi*fi/numc))*fsin(twopi*fj/numt);
  1417.             point[i][j][2] = rc * fsin(twopi * fi/numc);
  1418.  
  1419.             xc = rt*fcos(twopi*fj/numt);
  1420.             yc = rt*fsin(twopi*fj/numt);
  1421.             
  1422.             nx = point[i][j][0] - xc;
  1423.             ny = point[i][j][1] - yc;
  1424.             nz = point[i][j][2];
  1425.  
  1426.             n = fsqrt(nx*nx + ny*ny + nz*nz);
  1427.  
  1428.             norm[i][j][0] = nx/n;
  1429.             norm[i][j][1] = ny/n;
  1430.             norm[i][j][2] = nz/n;
  1431.         }
  1432.     }
  1433. }
  1434.  
  1435.  
  1436. /* set the cross sectional and torus radius */
  1437. void settorus(float rc, float rt)
  1438. {
  1439.     inittorus(rc,rt,torus_point,torus_norm);
  1440.     torus_initialized = TRUE;
  1441. }
  1442.     
  1443.  
  1444. /* wireframe torus */
  1445. void wtorus(void)
  1446. {
  1447.     int i, j;
  1448.     int numc = TORUS_NUMC, numt = TORUS_NUMT;
  1449.  
  1450.     if (! torus_initialized)
  1451.         settorus(TORUS_RAD_XC,TORUS_RAD);
  1452.  
  1453.     for (i = 0; i < numc; i++)
  1454.     {
  1455.         for (j = 0; j < numt; j++)
  1456.         {
  1457.             bgnclosedline();
  1458.                 v3f(torus_point[(i+1)%numc][j]);
  1459.                 v3f(torus_point[i][j]);
  1460.                 v3f(torus_point[(i+1)%numc][(j+1)%numt]);
  1461.             endclosedline();
  1462.             
  1463.             bgnclosedline();
  1464.                 v3f(torus_point[i][j]);
  1465.                 v3f(torus_point[(i+1)%numc][(j+1)%numt]);
  1466.                 v3f(torus_point[i][(j+1)%numt]);
  1467.             endclosedline();
  1468.         }
  1469.     }
  1470. }
  1471.  
  1472.  
  1473. /* filled torus */
  1474. void ftorus(void)
  1475. {
  1476.     int i, j;
  1477.     int numc = TORUS_NUMC, numt = TORUS_NUMT;
  1478.  
  1479.     if (! torus_initialized)
  1480.         settorus(TORUS_RAD_XC,TORUS_RAD);
  1481.  
  1482.     for (i = 0; i < numc; i++)
  1483.     {
  1484.         bgntmesh();
  1485.             n3f(torus_norm[(i+1)%numc][0]);
  1486.             v3f(torus_point[(i+1)%numc][0]);
  1487.             for (j = 0; j < numt; j++)
  1488.             {
  1489.                 n3f(torus_norm[i][j]);
  1490.                 v3f(torus_point[i][j]);
  1491.                 n3f(torus_norm[(i+1)%numc][(j+1)%numt]);
  1492.                 v3f(torus_point[(i+1)%numc][(j+1)%numt]);
  1493.             }
  1494.             n3f(torus_norm[i][0]);
  1495.             v3f(torus_point[i][0]);
  1496.         endtmesh();
  1497.     }
  1498. }
  1499.  
  1500.  
  1501. /************************************************************
  1502. SPHERE
  1503. ************************************************************/
  1504.  
  1505. /* how many levels of sphere tesselation */
  1506. #define FILLED_SPHERE_TESSELATION 8
  1507. #define WIRE_SPHERE_TESSELATION 4
  1508.  
  1509.  
  1510. /* wireframe sphere */
  1511. void wsphere(void)
  1512. {
  1513.     /* radius, Tx, Ty, Tz */
  1514.     static float v[]={0.0,0.0,0.0,1.0};
  1515.     
  1516.     sphmode(SPH_TESS,SPH_ICOS);
  1517.     sphmode(SPH_DEPTH,WIRE_SPHERE_TESSELATION);
  1518.     sphmode(SPH_PRIM,SPH_LINE);
  1519.  
  1520.     sphdraw(v);
  1521. }
  1522.  
  1523.  
  1524. /* filled sphere */
  1525. void fsphere(void)
  1526. {
  1527.     /* radius, Tx, Ty, Tz */
  1528.     static float v[]={0.0,0.0,0.0,1.0};
  1529.  
  1530.     sphmode(SPH_TESS,SPH_ICOS);
  1531.     sphmode(SPH_DEPTH,FILLED_SPHERE_TESSELATION);
  1532.     sphmode(SPH_PRIM,SPH_MESH);
  1533.         
  1534.     sphdraw(v);
  1535. }
  1536.  
  1537. /* wireframe hemisphere */
  1538. void whemisphere(void)
  1539. {
  1540.     /* radius, Tx, Ty, Tz */
  1541.     static float v[]={0.0,0.0,0.0,1.0};
  1542.     
  1543.     sphmode(SPH_TESS,SPH_ICOS);
  1544.     sphmode(SPH_HEMI,TRUE);
  1545.     sphmode(SPH_DEPTH,WIRE_SPHERE_TESSELATION);
  1546.     sphmode(SPH_PRIM,SPH_LINE);
  1547.  
  1548.     sphdraw(v);
  1549.     sphmode(SPH_HEMI,FALSE);
  1550. }
  1551.  
  1552.  
  1553. /* filled hemisphere */
  1554. void fhemisphere(void)
  1555. {
  1556.     /* radius, Tx, Ty, Tz */
  1557.     static float v[]={0.0,0.0,0.0,1.0};
  1558.  
  1559.     sphmode(SPH_TESS,SPH_ICOS);
  1560.     sphmode(SPH_HEMI,TRUE);
  1561.     sphmode(SPH_DEPTH,FILLED_SPHERE_TESSELATION);
  1562.     sphmode(SPH_PRIM,SPH_MESH);
  1563.         
  1564.     sphdraw(v);
  1565.     sphmode(SPH_HEMI,FALSE);
  1566. }
  1567.  
  1568. /* sphere drawn with points */
  1569. void psphere()
  1570. {
  1571.     /* radius, Tx, Ty, Tz */
  1572.     static float v[]={0.0,0.0,0.0,1.0};
  1573.  
  1574.     sphmode(SPH_TESS,SPH_ICOS);
  1575.     sphmode(SPH_DEPTH,FILLED_SPHERE_TESSELATION);
  1576.     sphmode(SPH_PRIM,SPH_POINT);
  1577.         
  1578.     sphdraw(v);
  1579. }    
  1580.  
  1581.  
  1582. /************************************************************
  1583. AXES
  1584. ************************************************************/
  1585.  
  1586. /* draws a wireframe set of right-handed axes */
  1587. void axes(void)
  1588. {
  1589.     bgnline();
  1590.         v3f(center);
  1591.         v3f(right);
  1592.     endline();
  1593.     cmov(right[0],right[1],right[2]);
  1594.     charstr("X");
  1595.  
  1596.     bgnline();
  1597.         v3f(center);
  1598.         v3f(top);
  1599.     endline();
  1600.     cmov(top[0],top[1],top[2]);
  1601.     charstr("Y");
  1602.  
  1603.     bgnline();
  1604.         v3f(center);
  1605.         v3f(front);
  1606.     endline();
  1607.     cmov(front[0],front[1],front[2]);
  1608.     charstr("Z");
  1609. }
  1610.  
  1611.  
  1612. /************************************************************
  1613. BEACHBALL
  1614. ************************************************************/
  1615.  
  1616. /* Number of colored stripes. Should be even to look right */
  1617. #define BEACHBALL_STRIPES 12
  1618.  
  1619. /* Default number of polygons  making up a stripe. Should be even */
  1620. #define BEACHBALL_POLYS 16
  1621.  
  1622. /* array of vertices making up a stripe */
  1623. static vector stripe_point[BEACHBALL_POLYS + 3];
  1624.  
  1625. /* has the beachball been initialized */
  1626. static Boolean beachball_initialized = FALSE;
  1627.  
  1628. /* Number of polygons making up a stripe */
  1629. static int beachball_stripes;
  1630.  
  1631. /* Number of vertices making up a stripe */
  1632. static int stripe_vertices;
  1633.  
  1634. /*
  1635. Initializes beachball_point array to be a stripe of unit radius.
  1636. */
  1637. void setbeachball(int stripes)
  1638. {
  1639.     int i,j;
  1640.     float x,y,z; /* vertex points */
  1641.     float theta,delta_theta; /* angle from top pole to bottom pole */
  1642.     float offset; /* offset from center of stripe to vertex */
  1643.     float cross_radius; /* radius of cross section at current latitude */
  1644.     float cross_theta; /* angle occupied by a stripe  */
  1645.     
  1646.     beachball_stripes = stripes;
  1647.  
  1648.     /* polys distributed by even angles from top to bottom */
  1649.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  1650.     theta = delta_theta;
  1651.  
  1652.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  1653.     
  1654.     j = 0;
  1655.  
  1656.     stripe_point[j][0] = top[0];
  1657.     stripe_point[j][1] = top[1];
  1658.     stripe_point[j][2] = top[2];
  1659.     j++;
  1660.  
  1661.     for (i = 0; i < BEACHBALL_POLYS; i += 2)
  1662.     {
  1663.         cross_radius = fsin(theta);
  1664.         offset = cross_radius * ftan(cross_theta/2.0);
  1665.  
  1666.         stripe_point[j][0] = - offset;
  1667.         stripe_point[j][1] = fcos(theta);
  1668.         stripe_point[j][2] = cross_radius;
  1669.         j++;
  1670.         
  1671.         stripe_point[j][0] = offset;
  1672.         stripe_point[j][1] = stripe_point[j-1][1];
  1673.         stripe_point[j][2] = stripe_point[j-1][2];
  1674.         j++;
  1675.         
  1676.         theta += delta_theta;
  1677.     }        
  1678.     
  1679.     stripe_point[j][0] = bottom[0];
  1680.     stripe_point[j][1] = bottom[1];
  1681.     stripe_point[j][2] = bottom[2];
  1682.  
  1683.     stripe_vertices = j + 1;
  1684.  
  1685.     beachball_initialized = TRUE;
  1686. }    
  1687.  
  1688. /*
  1689. Draws a cononical beachball. The colors are cpack values when in RGBmode,
  1690. colormap indices when in colormap mode.
  1691. */
  1692. void beachball(unsigned long c1, unsigned long c2)
  1693. {
  1694.     long mode;
  1695.     float angle, delta_angle;
  1696.     int i,j;
  1697.     
  1698.  
  1699.     if (! beachball_initialized)
  1700.         setbeachball(BEACHBALL_STRIPES);
  1701.  
  1702.     mode = getdisplaymode();
  1703.  
  1704.     angle = 0.0;
  1705.     delta_angle = 360.0/(float)beachball_stripes;
  1706.  
  1707.     for (i = 0; i < beachball_stripes; i++)
  1708.     {
  1709.         switch(mode)
  1710.         {
  1711.             case DMSINGLE:
  1712.             case DMDOUBLE:
  1713.                 if ( i%2 == 0)
  1714.                     color(c1);
  1715.                 else
  1716.                     color(c2);
  1717.  
  1718.                 break;
  1719.  
  1720.             case DMRGB:
  1721.             case DMRGBDOUBLE:
  1722.                 if ( i%2 == 0)
  1723.                     cpack(c1);
  1724.                 else
  1725.                     cpack(c2);
  1726.  
  1727.                 break;
  1728.         }
  1729.                     
  1730.         pushmatrix();
  1731.             rot(angle, 'y');
  1732.             angle += delta_angle;
  1733.  
  1734.             bgntmesh();
  1735.                 for (j = 0; j < stripe_vertices; j++)
  1736.                     v3f(stripe_point[j]);
  1737.             endtmesh();
  1738.         popmatrix();
  1739.     }
  1740. }
  1741.  
  1742.